#pragma once

#include<iostream>

namespace Study
{
	template<class T>
	struct list_node
	{
		T _date;
		list_node<T>* _next;
		list_node<T>* _prev;

		list_node(const T& x = T())
			:_date(x)
			,_next(nullptr)
			,_prev(nullptr)
		{
		}

	};

    template<class T>
	struct __list_iterator
	{
		typedef list_node<T> Node;
		typedef __list_iterator<T> self;

		Node* _node;

		__list_iterator(Node* node)
			:_node(node)
		{}

		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		T& operator*()
		{
			return _node->_date;
		}

		bool operator!=(const self& s)
		{
			return _node != s._node;
		}

	};

	template<class T>
	class List
	{
	     typedef list_node<T> Node;

	public:

		typedef __list_iterator<T> iterator;

		iterator begin()
		{
			return _head->_next;
		}

		iterator end()
		{
			return _head;
		}


		void empty_Init()
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			_size = 0;
		}

		List()
		{
			empty_Init();
		}

		void push_back(const T& x)
		{
			Node* move = _head->_prev;
			Node* newNode = new Node(x);

			newNode->_next = _head;
			newNode->_prev = move;

			move->_next = newNode;
			_head->_prev = newNode;
		}

	private:
		Node* _head;
		size_t _size;
	};
}